<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<meta charset="UTF-8">
<link rel="stylesheet" href="/resource/bootstrap4/css/bootstrap.css">
<script src="/resource/js/jquery-3.2.1.js"></script>
<script src="/resource/upload/webuploader.js"></script>
<script type="text/javascript">
    var base = "${pageContext.request.contextPath}";
    var gUploadInfo={
        fileAllNum:0,
        fileAllSize:0,
        successNum:0,
        successSize:0,
        percentages:{} // 所有文件的进度信息，key为file id
    }

    var batchWebUpload;

$(function(){
	var fileCheckUrl=base+"/mmcrofile/checkFile";//判断服务器是否存在该文件
	var checkChunkUrl=base+"/mmcrofile/checkChunk";//判断服务器是否存在该分片
	var mergeChunksUrl=base+"/mmcrofile/mergeChunks";//合并文件请求地址

    WebUploader.Uploader.register({
        "before-send-file":"beforeSendFile",
        "before-send":"beforeSend",
        "after-send-file":"afterSendFile"},{
        //所有分块进行上传之前调用
    	//所有分块进行上传之前调用
        beforeSendFile:function(file){
            //创建延迟对象
            var deferred = WebUploader.Deferred();
            //1.计算文件的唯一标记，用于断点续传和秒传,获取文件前2m的md5值，越小越快，
            // 防止碰撞，可以把文件名文件大小和md5拼接作为文件唯一标识
            (new WebUploader.Uploader()).md5File(file,0,2*1024*1024).progress(function(percentage){

            }).then(function(val){
                    file.fileMd5=val;// 文件md5码
                    //2.请求后台是否保存过该文件，如果存在，则跳过该文件，实现秒传功能
                    $.ajax({
                        type:"POST",
                        url:fileCheckUrl,
                        data:{
                            fileMd5:val,//文件唯一标记
                            fileSize:file.size,
                            fileName:file.name
                        },
                        dataType:"json",
                        success:function(response){
                        	console.log(response);
                            if(response.success){
                            	// 更新文件进度  秒传
                                updateFileProgress(file,100,"已传");
                            	batchWebUpload.skipFile(file);
                                gUploadInfo.successNum++;
                                gUploadInfo.successSize+=file.size;
                                file.serverFile=response.fileName;
                                //如果存在，则跳过该文件，秒传成功
                                deferred.reject();
                            }else{
                                //继续上传
                                deferred.resolve();
                            }
                        }
                        }
                    );

                });
            //返回deffered
            return deferred.promise();
        },

        //如果分片上传，则 每个分块上传之前调用此函数
        //block:代表当前分块对象
       beforeSend:function(block){
            //向后台发送当前文件的唯一标记，用于后台创建保存分块文件的目录
    	 //1.请求后台是否保存过当前分块，如果存在，则跳过该分块文件，实现断点续传功能
           var deferred = WebUploader.Deferred();
           //请求后台是否保存完成该文件信息，如果保存过，则跳过，如果没有，则发送该分块内容
           $.ajax({
               type:"POST",
               url:checkChunkUrl,
               data:{
                   //文件唯一标记,务必不要用file.fileMd5，
                   fileMd5: block.file.fileMd5,
                   //当前分块下标
                   chunk:block.chunk,
                   //当前分块大小
                   chunkSize:block.end-block.start
               },
               dataType:"json",
               success:function(response){
                   if(response.success){
                	   //分块存在，跳过该分块
                       deferred.reject();
                   }else{
                	   //分块不存在或者不完整，重新发送该分块内容
                       deferred.resolve();
                   }
               }
               }
           );
           //携带当前文件的唯一标记到后台，用于让后台创建保存该文件分块的目录
           return deferred.promise(); 
       },
       //所有分块上传成功之后调用此函数
       afterSendFile:function(file){//前台通知后台合并文件
    	   //1.如果分块上传，则通过后台合并所有分块文件 ，请求后台合并文件
             $.ajax({
                 type:"POST",
                 url:mergeChunksUrl,
                 data:{
                     //文件唯一标记
                     fileMd5:file.fileMd5,
                     //文件名称
                     fileName:file.name
                 },
                 dataType:"json",
                 success:function(response){
                	updateFileProgress(file,100,"完成")//设置进度条百分比
                     gUploadInfo.successNum++;
                     gUploadInfo.successSize+=file.size;
                	file.serverFile=response.fileName;
                 }
             });
       }
    });	

// 更新页面文件上传到的进度
var  updateFileProgress=function(file,percent,status){
        //<div class="progress-bar progress-bar-striped bg-info" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">25%</div>
        $("#"+file.id).find(".progress-bar").attr("style","width: "+parseInt(percent)+"%");
        $("#"+file.id).find(".progress-bar").attr("aria-valuenow",parseInt(percent) + "%");
        $("#"+file.id).find(".progress-bar").html(parseInt(percent)+"%")
        $("#"+file.id).find(".percent").html(parseInt(percent)+"%");
        $("#"+file.id).find(".status").html(status);
}

batchWebUpload = WebUploader.create({ 
	auto:false,
    pick: {
        id: $("#btnFileSelect"),//指定选择文件的按钮容器，不指定则不创建按钮。
        //label : title,
        //innerHTML : title,
        multiple :true //开启文件多选
    },
    flash:base+'/staticresource/webuploader/Uploader.swf',//ie9一下会自动使用flash上传
    server: base+"/mmcrofile/uploadChunks",
    //压缩图片，如果图片尺寸超过设置的尺寸，会自动压缩图片，必要时会裁剪
    compress:{
		width: 600,
		height: 600,
		// 图片质量，只有type为`image/jpeg`的时候才有效。
		quality: 90,
		// 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.
		allowMagnify: false,
		// 是否允许裁剪
		crop: false,
		// 是否保留头部meta信息。
		preserveHeaders: true,
		// 如果发现压缩后文件大小比原来还大，则使用原来图片
		// 此属性可能会影响图片自动纠正功能
		noCompressIfLarger: false
    },
	// 单位字节，如果图片大小小于此值，不会采用压缩。512k  512*1024，如果设置为0，原图尺寸大于设置的尺寸就会压缩；如果大于0，只有在原图尺寸大于设置的尺寸，并且图片大小大于此值，才会压缩
	compressSize: 0,
	fileNumLimit : 10,//验证文件总数量, 超出则不允许加入队列,默认值：undefined,如果不配置，则不限制数量
	fileSizeLimit : 10*1024*1024*1024, //1kb=1024*1024,验证文件总大小是否超出限制, 超出则不允许加入队列。
	fileSingleSizeLimit :5*1024*1024, //验证单个文件大小是否超出限制, 超出则不允许加入队列。
	chunked:true,//是否开启分片上传
	threads:3,
	threads:3,
	chunkSize:5*1024*1024,//如果要分片，每一片的文件大小  *1024
    prepareNextFile:false//在上传当前文件时，准备好下一个文件,请设置成false，不然开启文件多选你浏览器会卡死
});

//当文件上传成功时触发。file {File} File对象, response {Object}服务端返回的数据
batchWebUpload.on('uploadSuccess',function(file,response){
    console.log("-----文件上传完成-----0000" + file)
    file.serverFile=response.fileName;
	if(response.success){
		console.log(response);
	}
})
//错误类型。文件验证失败触发
batchWebUpload.on("error",function(type,file){
	console.log(type);
	if (type=="Q_TYPE_DENIED"){
        alert("只能上传gif,jpg,jpeg,bmp,png格式文件");
    }else if(type=="Q_EXCEED_SIZE_LIMIT"){
    	alert("所有的文件大小总和不能超过10G");
    }else if(type=='F_EXCEED_SIZE'){
        alert("单个文件大小不能超过5M");
    }else if(type=='Q_EXCEED_NUM_LIMIT'){
        alert(typeName+"最多只能上传10个");
    }else if(type=='F_DUPLICATE'){
        alert(file.name+"已经在上传队列，请勿重复上传");
    }else{
        alert("上传出错");
    }
}) 


//文件加入队列
batchWebUpload.on("fileQueued",function(file){
    gUploadInfo.fileAllNum++;
    gUploadInfo.fileAllSize+=file.size;

	var fileSize = (file.size/1024/1024.0).toFixed(2)+"M";



	$("#fileList").append(`
	     <tr id="`+file.id+`" style="height:10px " >
                    <th style="white-space:nowrap;text-overflow:ellipsis;overflow:hidden;max-width:100px">`+file.name+`</th>
                    <td>`+file.ext+`</td>
                    <td>`+fileSize+`</td>
                    <td>
                        <div class="progress">
                            <div class="progress-bar progress-bar-striped bg-info" role="progressbar" style="width: 50%" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100">25%</div>
                        </div>
                    </td>
                    <td class="percent">%25</td>
                    <td class="status"></td>
                </tr>
	    `);

	//绑定事件
	$("#pause_Btn_"+file.id).bind('click',function(){
        console.log("暂停了--------" + file.id)
		batchWebUpload.stop(file);
	})
	
	$("#continue_Btn_"+file.id).bind('click',function(){
	    console.log("继续了--------" + file.id)
		batchWebUpload.upload(file);
	})
	
	$("#delete_Btn_"+file.id).bind('click',function(){
        console.log("删除了--------" + file.id)
		batchWebUpload.removeFile( file, true );//从文件队列移除
	})

    gUploadInfo.percentages[ file.id ] = [ file.size, 0 ];
	file.on('statuschange', function( cur, prev ) {
		// 成功
		if ( cur === 'error' || cur === 'invalid' ) {
            gUploadInfo.percentages[ file.id ][ 1 ] = 1;
		}  else if ( cur === 'queued' ) {
            gUploadInfo.percentages[ file.id ][ 1 ] = 0;
		} 
	})
	$("#"+file.id).find('.percent').html("0%");
	updateFileProgress(file,0,"待传");

});

/**从文件队列移除**/
batchWebUpload.on('fileDequeued', function( file ) {
    gUploadInfo.fileAllNum--;
    gUploadInfo.fileAllSize-=file.size;
	delete gUploadInfo.percentages[ file.id ];
});

/**上传之前**/
batchWebUpload.on('uploadBeforeSend', function( block, data, headers ) {
	data.fileMd5 = block.file.fileMd5;
	//block.file.chunks = block.chunks;//当前文件总分片数量
	data.chunks = block.file.chunks;
});


/**上传过程中触发，携带上传进度**/
batchWebUpload.on('uploadProgress',function(file ,percentage){
	var percent=(percentage*100 ).toFixed(2)+"%";
    updateFileProgress(file,percentage*100,"上传中")//设置进度条百分比
	
	if(JSON.stringify(gUploadInfo.percentages) != "{}"){
        gUploadInfo.percentages[ file.id ][ 1 ] = percentage;
	}
	if(percentage==1){
        gUploadInfo.percentages[ file.id ][ 1 ] = 1;
	}
})
 batchWebUpload.on( 'all', function( type ,file) {
	updateTotalProgress();
	switch( type ) {
	  case 'uploadComplete':
			//parentId = file.id;
            gUploadInfo.percentages[ file.id ][ 1 ] = 1;
         break;
     case 'uploadFinished':
         var names  = batchWebUpload.getFiles().map(file=>{return file.serverFile;}).join();
         var md5s  = batchWebUpload.getFiles().map(file=>{return file.fileMd5;}).join();
         try {
             // 上传完成后回调函数
             var fn = eval("uploadOk");
             if (typeof (fn) === 'function') {
                 fn(names,md5s);
             } else {
                 console.log(f + "函数不存在！");
             }
         } catch (e) {

         }
        break;
     case 'uploadProgress':
         break;
     case 'uploadStart':
         break;
     case 'stopUpload':
         break;

 }
 })
})


function startAll(file){
	batchWebUpload.upload(file);
}

function stopUpload(file){
	if(file==undefined){
		batchWebUpload.stop();
	}else{
		batchWebUpload.stop(file);
	}
}

function cancelFile(file){
	batchWebUpload.cancelFile(file);
}


/**设置总百分比**/
function updateTotalProgress() {
	
	var fize = (gUploadInfo.fileAllSize/1024/1024.0).toFixed(2);
	var sSize = (gUploadInfo.successSize/1024/1024.0).toFixed(2);
	
	$("#fileQueueNum").text(gUploadInfo.fileAllNum)
	$("#fileQueueSize").text(fize);
    var loaded = 0;
    var total = 0;
   
    var percent = 0;;

    $.each( gUploadInfo.percentages, function( k, v ) {
        total += v[ 0 ];
        loaded += v[ 0 ] * v[ 1 ];
    } );
    percent = total ? loaded / total : 0;
    $("#successNum").text(gUploadInfo.successNum);
    $("#successSize").text(sSize);
    var show_pe= Math.round( percent * 100 ) + '%';
    $("#summaryInfo").find(".progress-bar").attr("style","width: "+show_pe);
    $("#summaryInfo").find(".progress-bar").attr("aria-valuenow",show_pe);
    $("#summaryInfo").find(".progress-bar").html(show_pe)
}

/*function uploadOk(fileNames){
   alert(fileNames);
}*/
</script>

<div class="container" style="width: 80%; height:500px">
    <div>
        <table class="table table-bordered table-lg table-dark"
               style="font-size: 12px;" >
            <thead>
            <tr style="height:16">
                <th colspan="6">
                    <button type="button" id="btnFileSelect" class="btn btn-success btn-sm">请选择文件</button>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                    <button type="button" class="btn btn-danger btn-sm" onclick="startAll()">&nbsp;&nbsp;开&nbsp;&nbsp;&nbsp;始&nbsp;&nbsp;</button>
                    <%--<button type="button" class="btn btn-warning btn-sm" onclick="stopUpload()">停止</button>--%>
                </th>
            </tr>
            </thead>
            <thead>
            <tr style="margin-top:0px">
                <th width="32%">文件名</th>
                <th width="7%">类型</th>
                <th width="7%">大小</th>
                <th width="40%">进度</th>
                <th width="7%">比例</th>
                <th width="7%">状态</th>
            </tr>
            </thead>
            <tbody id="fileList">
            </tbody>
            <tfoot id="fileInfo">
            <tr id="summaryInfo">
                <td colspan="2">
                    <span>选中<span id="fileQueueNum">0</span>个文件，共<span id="fileQueueSize">0</span>M。</span><br>
                    <span>上传成功<span id="successNum">0</span>个文件，共<span id="successSize">0</span>M。</span>
                </td>
                <td colspan="3">
                    <div class="progress">
                        <div class="progress-bar progress-bar-striped" role="progressbar" style="width: 10%" aria-valuenow="10" aria-valuemin="0" aria-valuemax="100"></div>
                    </div>
                </td>
                <td colspan="1" >
                </td>
            </tr>
            </tfoot>
        </table>
    </div>
</div>